package com.gxkj.drm.service;


import com.gxkj.drm.entitys.ResourceManage;
import com.gxkj.drm.enums.SendType;
import com.gxkj.drm.uitls.MessageSmsUtil;
import com.gxkj.drm.uitls.ObjectNameUtil;
import com.gxkj.drm.uitls.ThreadUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.management.Attribute;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Service
public class PushMananger {

    @Resource
    protected List<String> mobileList;

    private static final String JMX_URL = "service:jmx:rmi:///jndi/rmi://%s/server";

    private static final Logger logger = LoggerFactory.getLogger(PushMananger.class);

    /**
     * 创建远程连接
     * @param ip
     * @param timeOut
     * @param unit
     * @return
     */
    JMXConnector connectWithTimeout(final String ip, long timeOut, TimeUnit unit) {
        Future<JMXConnector> future;
        try {
            future = ThreadUtil.submit(new Callable<JMXConnector>() {
                JMXServiceURL url = new JMXServiceURL(String.format(JMX_URL, ip));

                @Override
                public JMXConnector call() {
                    try {
                        Map<String, Object> env = new HashMap<String, Object>();
                        String[] credentials = new String[] {"pushManager", "GNYJ<$EDX&2C*^JFT"};
                        env.put("jmx.remote.credentials", credentials);
                        return JMXConnectorFactory.connect(url, env);
                    } catch (IOException e) {
                        logger.error(String.format("init remote service failed, ip=%s", ip), e);
                    }
                    return null;
                }
            });

            return future.get(timeOut, unit);
        } catch (Exception e) {
            logger.error(String.format("init remote service failed, ip=%s", ip), e);
        }

        return null;
    }

    /**
     * 推送属性值到远程
     * @param rm
     * @return
     */
    public boolean sendAttributeValue(ResourceManage rm, SendType type) {
        JMXConnector jmxc = null;

        try {
            jmxc = this.connectWithTimeout(rm.getIp(), 3000, TimeUnit.MILLISECONDS);
            if (jmxc == null) {
                if (type.equals(SendType.THIRD_PARTY)) {
                    this.sendSms(String.format("cluster=%s, sendAttributeValue failed, ip=%s, resourceId=%s, %s=%s",
                            rm.getCluster(), rm.getIp(), rm.getId(), rm.getAttribute(), rm.getAttributeValue()));
                }
                return false;
            }
            MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
            mbsc.setAttribute(ObjectNameUtil.getObjectName(rm.getResourcePath()),
                    new Attribute(rm.getAttribute(), rm.getAttributeValue()));
            if (type.equals(SendType.SEND)) {
                logger.info(String.format("sendAttributeValue successed, ip=%s, resourceId=%s, %s=%s", rm.getIp(),
                        rm.getId(), rm.getAttribute(), rm.getAttributeValue()));
            } else if (type.equals(SendType.THIRD_PARTY)) {
                logger.info(String.format("third party successed, ip=%s, resourceId=%s, %s=%s", rm.getIp(),
                        rm.getId(), rm.getAttribute(), rm.getAttributeValue()));
            } else {
                logger.info(String.format("init successed, ip=%s, resourceId=%s, %s=%s", rm.getIp(), rm.getId(),
                        rm.getAttribute(), rm.getAttributeValue()));
            }
        } catch (Exception e) {
            if (type.equals(SendType.THIRD_PARTY)) {
                this.sendSms(String.format("cluster=%s, sendAttributeValue failed, ip=%s, resourceId=%s, %s=%s",
                        rm.getCluster(), rm.getIp(), rm.getId(), rm.getAttribute(), rm.getAttributeValue()));
            }

            if (type.equals(SendType.SEND)) {
                logger.error(String.format("sendAttributeValue failed, ip=%s, resourceId=%s, %s=%s", rm.getIp(),
                        rm.getId(), rm.getAttribute(), rm.getAttributeValue()), e);
            } else if (type.equals(SendType.THIRD_PARTY)) {
                logger.error(String.format("third party failed, ip=%s, resourceId=%s, %s=%s", rm.getIp(),
                        rm.getId(), rm.getAttribute(), rm.getAttributeValue()), e);
            }else {
                logger.error(
                        String.format("init failed, ip=%s, resourceId=%s, %s=%s", rm.getIp(), rm.getId(),
                                rm.getAttribute(), rm.getAttributeValue()), e);
            }
            return false;
        } finally {
            if (jmxc != null) {
                try {
                    jmxc.close();
                } catch (IOException e) {
                    logger.error(
                            String.format("JMXConnector closed failed, ip=%s, resourceId=%s", rm.getIp(), rm.getId()),
                            e);
                }
            }
        }

        return true;
    }

    /**
     * 发送短信接口
     * @param message
     */
    private void sendSms(String message) {
        for (String phone : mobileList) {
            MessageSmsUtil.sendMessage(phone, message);
        }
    }
}
